#include <allegro.h>

#include "../setup.h"
#include "../map.h"
#include "../dungeon.h"
#include "../game.h"

#define SQ_SIZE 10

BITMAP* bmp_map = NULL;
static Map* map = NULL;

static void render_tile(int x, int y, int c_fill, int c_border)
{
	rectfill (bmp_map, x*SQ_SIZE, y*SQ_SIZE, x*SQ_SIZE + SQ_SIZE, y*SQ_SIZE + SQ_SIZE, c_fill);
	rect (bmp_map, x*SQ_SIZE, y*SQ_SIZE, x*SQ_SIZE + SQ_SIZE, y*SQ_SIZE + SQ_SIZE, c_border);
}

static void render_arrow(int x, int y, int up, int c_fill)
{
#define INDENT 2
	if (up)
	{
		triangle (bmp_map, x*SQ_SIZE + SQ_SIZE/2, y*SQ_SIZE + INDENT,
				       x*SQ_SIZE + INDENT, y*SQ_SIZE + SQ_SIZE - INDENT,
					   x*SQ_SIZE + SQ_SIZE - INDENT, y*SQ_SIZE + SQ_SIZE - INDENT,
			  		   c_fill);
	}
	else
	{
		triangle (bmp_map, x*SQ_SIZE + SQ_SIZE/2, y*SQ_SIZE + SQ_SIZE - INDENT,
				       x*SQ_SIZE + INDENT, y*SQ_SIZE + INDENT,
					   x*SQ_SIZE + SQ_SIZE - INDENT, y*SQ_SIZE + INDENT,
			  		   c_fill);
	}
#undef INDENT
}

static void render_square(int x, int y, int c_fill)
{
#define INDENT 3
	rectfill (bmp_map, x*SQ_SIZE + INDENT, y*SQ_SIZE + INDENT,
					   x*SQ_SIZE + SQ_SIZE - INDENT, y*SQ_SIZE + SQ_SIZE - INDENT,
					   c_fill);
#undef INDENT
}

static void render_circle(int x, int y, int c_fill)
{
#define INDENT 2
	circlefill (bmp_map, x*SQ_SIZE + SQ_SIZE/2, y*SQ_SIZE + SQ_SIZE/2, SQ_SIZE/2 - INDENT, c_fill);
#undef INDENT
}

void render_map(int layer)
{
	clear_bitmap(bmp_map);
	for (int y=0; y<MAP_HEIGHT; ++y) {
		for (int x=0; x<MAP_WIDTH; ++x) {
			switch (map_tile(map,x,y,layer)->type) {
				case TILE_UNDEFINED:
					render_tile(x, y, 0, 0);
					break;
				case TILE_FLOOR:
					render_tile(x, y, makecol32(50, 50, 50), makecol32(100, 100, 100));
					break;
				case TILE_WALL:
					render_tile(x, y, makecol32(200, 100, 0), makecol32(255, 150, 0));
					break;
				case TILE_DOOR:
					render_tile(x, y, 0, 0); //TODO
					break;
				case TILE_TELEPORTER:
					render_tile(x, y, makecol32(100, 100, 200), makecol32(200, 200, 255));
					render_circle(x, y, makecol32(200, 200, 255));
					break;
				case TILE_TRIGGER:
					render_tile(x, y, 0, 0); //TODO
					break;
				case TILE_TOGGLEABLE:
					render_tile(x, y, 0, 0); //TODO
					break;
				case TILE_EXIT_UP:
					render_tile(x, y, makecol32(100, 100, 100), makecol32(200, 200, 200));
					render_arrow(x, y, 1, makecol32(200, 200, 200));
					break;
				case TILE_EXIT_DOWN:
					render_tile(x, y, makecol32(100, 100, 100), makecol32(200, 200, 200));
					render_arrow(x, y, 0, makecol32(200, 200, 200));
					break;
				case TILE_EXIT_BETWEEN:
					render_tile(x, y, makecol32(100, 100, 100), makecol32(200, 200, 200));
					render_square(x, y, makecol32(200, 200, 200));
				default: break;
			}
		}
	}
}

int render_map_hl (coord_t hl1, coord_t hl2)
{
	char filename [255];
	for (int z = 0; z < map->num_layers; z++) {
		render_map(z);
		if (z == hl1.z) 
			rectfill (bmp_map, hl1.x*SQ_SIZE, hl1.y*SQ_SIZE, hl1.x*SQ_SIZE + SQ_SIZE, hl1.y*SQ_SIZE + SQ_SIZE, makecol(255,255,0));
		if (z == hl2.z) 
			rectfill (bmp_map, hl2.x*SQ_SIZE, hl2.y*SQ_SIZE, hl2.x*SQ_SIZE + SQ_SIZE, hl2.y*SQ_SIZE + SQ_SIZE, makecol(0,255,0));
		sprintf (filename, "map_%d.pcx", z);
		if (save_bitmap(filename, bmp_map, NULL) != 0) return 1;
	}
	return 0;
}

void dig_init (Map* m);
Rect dig_room (int width, int height, coord_t near);
void dig_tunnel (coord_t from, coord_t to, int (*is_room) (coord_t));

int main (int argc, char* argv[])
{
	char filename [255];
	
	load_allegro();
        //load_data (); /* from files */
	map = malloc(sizeof(Map));
	bmp_map = create_bitmap(MAP_WIDTH*SQ_SIZE, MAP_HEIGHT*SQ_SIZE);
	map_init(map, MAP_WIDTH, MAP_HEIGHT);
	
	PALETTE pal;
	get_palette(pal);

	int is_room (coord_t c) { return 0; }

	// working seeds list:
	// 0xffef3812
	// 838998093
	// 0x5720a38b
	// 0x5736a38b
	generate_amazing_maze(map, 0xbf289f92, NUM_DUNGEON_SEGMENTS);
	/*dig_init (map);
	dig_room (5, 5, (coord_t){0,0,0});
	dig_room (5, 5, (coord_t){7,0,0});
	dig_tunnel((coord_t){2,2,0}, (coord_t){7,2,0}, &is_room); */
	for (int z = 0; z < map->num_layers; z++) {
		render_map(z);
		sprintf (filename, "map_%d.pcx", z);
		save_bitmap(filename, bmp_map, pal);
	}
	free(map);
	destroy_bitmap(bmp_map);
	return 0;
}
END_OF_MAIN()

